package com.cmw.core.util;

import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Set;

/**
 * 工具类 <功能简述> <功能详细描述>
 * 
 * 
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class StringUtil extends StringHandler{

	/**
	 * 以yyyy-MM-dd为格式
	 */
	public static final String YMD = "yyyy-MM-dd";

	/**
	 * 以yyyy-MM-dd hh:mm为格式
	 */
	public static final String YMDHM = "yyyy-MM-dd hh:mm";

	/**
	 * 以yyyy-MM-dd hh:mm:ss为格式
	 */
	public static final String YMDHMS = "yyyy-MM-dd HH:mm:ss";

	
	/**
	 * 
	 * 判断是否为空 null、" "、"" 均返回true
	 * 
	 */
	public static boolean isBlank(String str) {
		boolean result = false;
		if (str == null||"".equals(str.trim())||"null".equals(str)) {
			result = true;
		}
		return result;
	}

	/**
	 * 
	 * 判断是否非空
	 * 
	 */
	public static boolean isNotBlank(String str) {
		return !isBlank(str);
	}

	/**
	 * 获取DATE时间
	 * 
	 * @return
	 */
	public static Date getDate() {
		return new java.sql.Date(System.currentTimeMillis());
	}

	/**
	 * 
	 * <功能简述> 获取当月有多少天 <功能详细描述>
	 * 
	 * @return [参数说明]
	 * 
	 * @return int [返回类型说明]
	 * @exception throws [异常类型] [异常说明]
	 * @see [类、类#方法、类#成员]
	 */

	public static int getCurrentMonthLastDay() {
		Calendar a = Calendar.getInstance();
		a.set(Calendar.DATE, 1);// 把日期设置为当月第一天
		a.roll(Calendar.DATE, -1);// 日期回滚一天，也就是最后一天
		int maxDate = a.get(Calendar.DATE);
		return maxDate;
	}

	/**
	 * 
	 * <功能简述> 得到指定月的天数 <功能详细描述>
	 * 
	 * @param year
	 *            指定年份
	 * @param month
	 *            指定月份
	 * @return [参数说明]
	 * 
	 * @return int [返回类型说明]
	 * @exception throws [异常类型] [异常说明]
	 * @see [类、类#方法、类#成员]
	 */
	public static int getDayOfMonth(int year, int month) {
		Calendar a = Calendar.getInstance();
		a.clear();
		a.set(Calendar.YEAR, year);
		a.set(Calendar.MONTH, month - 1);
		// a.set(Calendar.DATE, 1);//把日期设置为当月第一天
		// a.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
		int maxDate = a.getActualMaximum(Calendar.DATE);
		return maxDate;
	}

	/**
	 * 
	 * 获取指定格式的系统当前时间
	 * 
	 * @param dateFormat
	 *            时间格式
	 * 
	 */
	public static String getSystemDate(String dateFormat) {
		Calendar c = Calendar.getInstance(Locale.CHINESE);
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		return sdf.format(c.getTime());
	}

	/**
	 * 
	 * 获取yyyy-MM-dd HH:mm:ss格式的系统当前时间
	 * 
	 */
	public static String getSystemDate() {
		return getSystemDate("yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 
	 * <功能简述> 把系统取出的时间转换成yyyy-MM-dd HH:mm时间格式 <功能详细描述>
	 * 
	 * @param datetime
	 * @return [参数说明]
	 * 
	 * @return String [返回类型说明]
	 * @exception throws [异常类型] [异常说明]
	 * @see [类、类#方法、类#成员]
	 */
	public static String convertDate(String datetime) {
		try {
			if (datetime != null && datetime.length() > 0) {
				SimpleDateFormat sdf = new SimpleDateFormat(
						"yyyy-MM-dd HH:mm:ss");
				Date date = sdf.parse(datetime);
				return sdf.format(date);
			} else {
				return "";
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 
	 * <功能简述> 把系统取出的时间转换成指定的时间格式 <功能详细描述>
	 * 
	 * @param datetime
	 *            要转换的时间
	 * @param pattern
	 *            转换的时间格式
	 * @return [参数说明]
	 * 
	 * @return String [返回类型说明]
	 * @exception throws [异常类型] [异常说明]
	 * @see [类、类#方法、类#成员]
	 */
	public static String convertDate(String datetime, String pattern) {
		try {
			if (datetime != null && datetime.length() > 0) {
				SimpleDateFormat sdf = new SimpleDateFormat(pattern);
				Date date = sdf.parse(datetime);
				return sdf.format(date);
			} else {
				return "";
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 如果str中的每一位都是数字，返回true，否则返回false
	 * 
	 */
	public static boolean isNumberString(String str) {
		boolean result = true;
		if (str != null) {
			for (int i = 0; i < str.length(); i++) {
				if (!Character.isDigit(str.charAt(i))) {
					result = false;
					break;
				}
			}
		}
		return result;
	}

	/**
	 * 
	 * 比较时间大小,返回 0 时间相等 小于0 开始时间小于结束时间 大于0 开始时间大于结束时间
	 * 
	 */
	public static int timeDifference(String beginTime, String endTime) {
		java.text.DateFormat df = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss");
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		try {
			System.out.println("datadata");
			c1.setTime(df.parse(beginTime));
			c2.setTime(df.parse(endTime));
			System.out.println("datadata");
		} catch (ParseException e) {
			System.err.println("格式不正确");
		}
		return c1.compareTo(c2);
	}

	/**
	 * 比较一时间点是否在某个时间范围内 compareTime时间在beginTime和endTime之间（包括相等）返回true，否则返回false
	 * 
	 */
	public static boolean timeDifference(String beginTime, String endTime,
			String compareTime) {
		boolean result = false;
		if (timeDifference(beginTime, compareTime) <= 0
				&& timeDifference(endTime, compareTime) >= 0) {
			result = true;
		}
		return result;
	}

	/**
	 * 
	 * 计算两个日期的天数差并返回，日期格式yyyy-MM-dd
	 * 
	 */
	public static int getIntervalDays(String beginTime, String endTime) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		long millisecond = 0L;
		try {
			millisecond = format.parse(endTime).getTime()
					- format.parse(beginTime).getTime();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		int day = (int) (millisecond / 24L / 60L / 60L / 1000L);
		return day;
	}

	/**
	 * 通过当前时间与规定办理天数，算出结束时间
	 * 
	 * @param to
	 * @return
	 */
	@SuppressWarnings("all")
	public static String dateAdd(String to, Calendar strDate) {

		// 日期处理模块 (将日期加上某些天或减去天数)返回字符串
		int strTo;
		try {
			strTo = Integer.parseInt(to);
		} catch (Exception e) {
			System.out.println("日期标识转换出错!   :   \n::: " + to + "不能转为数字型 ");
			e.printStackTrace();
			strTo = 0;
		}
		strDate.add(strDate.DATE, strTo); // 日期减 如果不够减会将月变动
		// 生成 (年-月-日)字符串
		String meStrDate = strDate.get(strDate.YEAR) + "-"
				+ String.valueOf(strDate.get(strDate.MONTH) + 1) + "-"
				+ strDate.get(strDate.DATE) + " "
				+ strDate.get(strDate.HOUR_OF_DAY) + ":"
				+ strDate.get(strDate.MINUTE) + ":"
				+ strDate.get(strDate.SECOND);

		return meStrDate;
	}

	/**
	 * 转换时间
	 * 
	 * @param strDate
	 * @return
	 */
	@SuppressWarnings("all")
	public static String toDate(Calendar strDate) {
		String beginTime = strDate.get(strDate.YEAR) + "-"
				+ String.valueOf(strDate.get(strDate.MONTH) + 1) + "-"
				+ strDate.get(strDate.DATE) + " " + strDate.get(strDate.HOUR)
				+ ":" + strDate.get(strDate.MINUTE) + ":"
				+ strDate.get(strDate.SECOND);
		return beginTime;
	}

	/**
	 * Arraylist去重复数据
	 * 
	 * @param list
	 * @return
	 */
	@SuppressWarnings("all")
	public static List removeDuplicateWithOrder(List list) {
		Set set = new HashSet();
		List newList = new ArrayList();
		for (Iterator iter = list.iterator(); iter.hasNext();) {
			Object element = iter.next();
			if (set.add(element))
				newList.add(element);
		}
		return newList;
	}

	/**
	 * 将double转换为两位小数(此方法如果遇到不足两位小数的数字不会自动补充0，建议不使用) 返回double类型
	 * 
	 * @param num
	 * @return
	 */
	@Deprecated
	public static double convertDouble(double num) {
		DecimalFormat df = new DecimalFormat("#.00");
		double st = Double.parseDouble(df.format(num));

		return st;

	}

	/**
	 * 将double转换为两位小数，不足两位小数自动补0（返回String类型） 返回值如果强转double，最后一个0将丢失
	 * 
	 * @param num
	 *            要转换的数字
	 * @return
	 */
	public static String convertDoubleNew(double num) {
		if (num == 0)
			return "0.00";
		DecimalFormat df = new DecimalFormat("#.00");

		return df.format(ArithUtil.round(num, 2));
	}

	/**
	 * 
	 * <功能简述> 取小数点后两位，并四舍五入 <功能详细描述>
	 * 
	 * @param value
	 * @return [参数说明]
	 * 
	 * @return double [返回类型说明]
	 * @exception throws [异常类型] [异常说明]
	 * @see [类、类#方法、类#成员]
	 */
	public static double convert(double value) {
		long lg = Math.round(value * 100); // 四舍五入
		double d = lg / 100.0; // 注意：使用 100.0而不是 100
		return d;
	}

	/**
	 * 获得指定日期的后一天
	 * 
	 * @param specifiedDay
	 * @return
	 */
	public static String getSpecifiedDayAfter(String specifiedDay) {
		Calendar c = Calendar.getInstance();
		Date date = null;
		try {
			date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.setTime(date);
		int day = c.get(Calendar.DATE);
		c.set(Calendar.DATE, day + 1);

		String dayAfter = new SimpleDateFormat("yyyy-MM-dd")
				.format(c.getTime());
		return dayAfter;
	}

	/**
	 * 
	 * <功能简述> 获取指定时间所属周的星期几的时间 <功能详细描述>
	 * 
	 * @param date
	 *            指定时间 yyyy-MM-dd
	 * @param dayOfWeek
	 *            一周中的第几天
	 * @return [参数说明]
	 * 
	 * @return String [返回类型说明]
	 * @exception throws [异常类型] [异常说明]
	 * @see [类、类#方法、类#成员]
	 */
	public static String getDayOfWeek(String date, int dayOfWeek) {

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date d = null;
		Calendar cal = null;
		try {
			d = format.parse(date);
			cal = Calendar.getInstance();
			cal.setTime(d);
			cal.set(Calendar.DAY_OF_WEEK, dayOfWeek);
			System.out.println("currentMonday:" + format.format(cal.getTime()));
		} catch (ParseException e) { // TODO Auto-generated catch block
			e.printStackTrace();
		}
		return format.format(cal.getTime());
	}

	/**
	 * 
	 * 格式化日期，如果datetime为yyyy-MM-dd hh:mm:ss 则格式化为yyyy-MM-dd，如果为yyyy-MM-dd则直接返回
	 * 
	 */
	public static String formatDate(String datetime) {
		int index = datetime.indexOf(" ");
		if (index != -1) {
			return datetime.substring(0, index);
		}
		return datetime;
	}

	/**
	 * 
	 * 获取指定时间所属月，用传入天数代替天，返回一个新的时间，天数超过本月总天数则月份作相应变化 ？ 这个方法的作用令人费解 wby ？
	 * 
	 */
	public static String getDayOfMonth(String date, int dayOfMonth) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date d = null;
		Calendar cal = null;
		try {
			d = format.parse(date);
			cal = Calendar.getInstance();
			cal.setTime(d);
			cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);
			System.out.println("currentMonday:" + format.format(cal.getTime()));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return format.format(cal.getTime());
	}

	/**
	 * 得到上个月的今天 <功能简述> <功能详细描述>
	 * 
	 * @return [参数说明]
	 * @author chenqin
	 * 
	 * @return String [返回类型说明]
	 * @exception throws [异常类型] [异常说明]
	 * @see [类、类#方法、类#成员]
	 */
	public static String getNowOfLastMonth() {
		SimpleDateFormat aSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		GregorianCalendar aGregorianCalendar = new GregorianCalendar();
		aGregorianCalendar.set(Calendar.MONTH,
				aGregorianCalendar.get(Calendar.MONTH) - 1);
		String nowOfLastMonth = aSimpleDateFormat.format(aGregorianCalendar
				.getTime());
		return nowOfLastMonth;
	}

	/**
	 * 
	 * 得到下个月的今天
	 * 
	 */
	public static String getNowOfNextMonth(int dayNum) {
		SimpleDateFormat aSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		GregorianCalendar aGregorianCalendar = new GregorianCalendar();
		aGregorianCalendar.set(Calendar.MONTH,
				aGregorianCalendar.get(Calendar.MONTH) + dayNum);
		String nowOfLastMonth = aSimpleDateFormat.format(aGregorianCalendar
				.getTime());
		return nowOfLastMonth;
	}

	/**
	 * 得到本周时间 <功能简述> <功能详细描述>
	 * 
	 * @param format
	 * @return [参数说明]
	 * 
	 * @return String [返回类型说明]
	 * @exception throws [异常类型] [异常说明]
	 * @see [类、类#方法、类#成员]
	 */
	public static String getthisWeek() {
		Calendar cal = Calendar.getInstance();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); // 获取本周一的日期
		String start = df.format(cal.getTime());
		// 这种输出的是上个星期周日的日期，因为老外那边把周日当成第一天
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
		// 增加一个星期，才是我们中国人理解的本周日的日期
		cal.add(Calendar.WEEK_OF_YEAR, 1);
		String end = df.format(cal.getTime());
		return start + end;
	}

	/**
	 * 获取一个6位数字的验证码
	 * 
	 * @return
	 */
	public static String getValidcode() {
		Random random = new Random();
		int num = 100000 + random.nextInt(899999) + 1;

		return num + "";
	}

	/**
	 * 格式化数字，如大数值时以1.0000E方式时，转换为完整显示，不以科学计数法显示，并标以
	 * 
	 * @return 100,000,000.00
	 * @author hulicheng 2013-7-8 String
	 */
	public static String formateNumber(Object val) {
		try {
			return formateNumber(null == val ? "0.00" : val, true);
		} catch (Exception e) {
			return "0.00";
		}
	}

	public static String formateNumber(Object val, boolean groupingUsed) {
		val = (null == val) ? "0" : val;
		NumberFormat f = DecimalFormat.getInstance(Locale.CHINA);
		f.setMaximumFractionDigits(2);
		f.setMinimumFractionDigits(2);
		f.setGroupingUsed(groupingUsed);
		if(val instanceof Double){
			return f.format(val);	
		}else if(val instanceof String){
			return f.format(Double.parseDouble((String)val));
		}else{
			return f.format(val);
		}
			
		
	}

	/**
	 * 单位截取
	 * 
	 * @param args
	 */
	public static String cut(String value) {
		if(value==null) return null;
		if(value.endsWith("个")){
			return value.substring(0,value.length()-1);
		}else if(value.endsWith("元")){
			return value.substring(0,value.length()-1); 
		}else if(value.endsWith("天")){
			return value.substring(0,value.length()-1); 
		}else{
			return value;
		}
	}
	
	//拼接id类似in ('1','2','3')的语句(从集合转换)
	public static String hqlIDFromList(Object[] nids) {
		String hql = " in (";
		for (int i = 0; i < nids.length; i++) {
			if (i > 0) {
				hql += ",";
			}
			hql += "'" + nids[i] + "'";
		}
		hql += ")";
		return hql;
	}
	
	/**
	 * 根据当前current_env 指定的环境获取对应资源值
	 * @param resourceKey·资源KEY
	 * @return	返回对应的资源值
	 */
	public static String getResVal(String resourceKey){
		String _resourceKey = CURRENT_ENV +"_"+resourceKey;
		String val = GetResValue(_resourceKey);
		if(!isValidStr(val)){
			val = GetResValue(resourceKey);
		}
		return val;
	}
	
    /**
     * 根据用户名的不同长度，来进行替换 ，达到保密效果
     * @param userName 用户名
     * @return 替换后的用户名
     */
    public static String replaceWithStar(String userName) {
        return replaceWithStar(userName, null, 3, 2);
    }
	
    /**
     * 根据用户名的不同长度，来进行替换 ，达到保密效果
     * @param userName 用户名
     * @return 替换后的用户名
     */
    public static String replaceWithStar(String userName, String sigin ,int startCount, int endCount) {
        String userNameAfterReplaced = "";
        if (!isValidStr(userName)){
            return "";
        }
        int length = userName.length();
        if(length <= (startCount+endCount)){
        	return userName;
        }
        if(!StringHandler.isValidStr(sigin)) sigin = "***";
        String startStr = userName.substring(0,startCount);
        String endStr = userName.substring(length-endCount,length);
        userNameAfterReplaced = startStr+sigin+endStr;
        return userNameAfterReplaced;
    }

    /**
     * 判断字符串是否是长整型数字
     * @param value 字符串
     * @return 返回Boolean 值 [true:是长整型数字,false:非长整型数字]
     */
    public static boolean isLong(String value) {
     try {
	      Long.parseLong(value);
	      return true;
     } catch (NumberFormatException e) {
    	  return false;
     }
    }
    
    /**
     * 判断是否是 url 编码字符串
     * @param str 编码字符串	
     * @return	返回boolean值 [true:是编码字符串,false:非url编码字符串]
     */
    public static boolean isUrlDecode(String str){
    	return isUrlDecode(str, 3);
    }

    public static boolean isUrlDecode(String str, int len){
    	if(!StringHandler.isValidStr(str)) return false;
    	int count = 0;
    	char[] chars = str.toCharArray();
    	for(char ch : chars){
    		if(ch == '%') count++;
    	}
    	if(count >= len && str.length() > len) return true;
    	return false;
    }

	
	static final String CURRENT_ENV= GetResValue("current_env");
	
	public static void main(String[] args){
		String account = replaceWithStar("13922111489");
		System.out.println(account);
	}
	
	
	/**
	 * Springmvc中@RequestParam传值中文乱码解决方案
	 * @param str
	 * @return
	 */
	 public static String encodeStr(String str) {  
        try {  
        	if(!StringHandler.isValidObj(str)) return null;
            return new String(str.getBytes("ISO-8859-1"), "UTF-8").trim();  
        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
            return null;  
        }  
    }
	 
}
